#include "inicializacao.h"


void logica(int &comida,int &madeira,vector <ARVORE> &arvores, vector <VACA> &vacas, vector <CIDADAO> &aldeoes, ONIBUS townCenter, vector <BARRACK> barracas, vector<GUERREIRO> guerreiro)
{

    //if (agora - tempoDasVacas > 2)
    for (unsigned int i = 0; i < vacas.size(); i++)
    {
        if (vacas[i].estaViva) //só anda se estiver vida dã
            if (clock() > vacas[i].tempoMovimento)
            {
                vacas[i].tempoMovimento = clock() + CLOCKS_PER_SEC * 2 * VELOCIDADEDOJOGO;
                switch (rand()%4)
                {
                case 0:  //esquerda
                    if (!verificaSeHaAlgumaCoisa(vacas[i].x-1, vacas[i].y, vacas, arvores, aldeoes, townCenter, barracas, guerreiro))
                    {
                        vacas[i].x--;
                        break;
                    }
                case 1:
                    if (!verificaSeHaAlgumaCoisa(vacas[i].x, vacas[i].y+1, vacas, arvores, aldeoes, townCenter, barracas, guerreiro))
                    {
                        vacas[i].y++;
                        break;
                    }
                case 2:
                    if (!verificaSeHaAlgumaCoisa(vacas[i].x+1, vacas[i].y, vacas, arvores, aldeoes, townCenter, barracas, guerreiro))
                    {
                        vacas[i].x++;
                        break;
                    }
                case 3:
                    if (!verificaSeHaAlgumaCoisa(vacas[i].x, vacas[i].y-1, vacas, arvores, aldeoes, townCenter, barracas, guerreiro))
                    {
                        vacas[i].y--;
                    }
                    break;
                    if (!verificaSeHaAlgumaCoisa(vacas[i].x-1, vacas[i].y, vacas, arvores, aldeoes, townCenter, barracas, guerreiro))
                    {
                        vacas[i].x--;
                        break;
                    }
                    if (!verificaSeHaAlgumaCoisa(vacas[i].x, vacas[i].y+1, vacas, arvores, aldeoes, townCenter, barracas, guerreiro))
                    {
                        vacas[i].y++;
                        break;
                    }
                    if (!verificaSeHaAlgumaCoisa(vacas[i].x+1, vacas[i].y, vacas, arvores, aldeoes, townCenter, barracas, guerreiro))
                    {
                        vacas[i].x++;
                        break;
                    }
                    if (!verificaSeHaAlgumaCoisa(vacas[i].x, vacas[i].y-1, vacas, arvores, aldeoes, townCenter, barracas, guerreiro))
                        vacas[i].y--;
                    break;
                }
            }
    }        //tempoDasVacas = time(NULL);

    for(int i = 0; i < aldeoes.size(); i++)
    {
        bool andaNessa = true;
        andaNessa = true;
        if (aldeoes[i].tempoMovimento < clock())
        {
            aldeoes[i].tempoMovimento = clock() + float(CLOCKS_PER_SEC) * 0.5 * VELOCIDADEDOJOGO;

//int teste = aldeoes[i].oQueFazendo;
            if (aldeoes[i].recemEscolhido == true)
            {
                aldeoes[i].recemEscolhido = false;
                aldeoes[i].caminho = pathfind(aldeoes[i].x , aldeoes[i].y, aldeoes[i].xDest, aldeoes[i].yDest, vacas, arvores, aldeoes, townCenter, barracas, guerreiro);
            }

            if (aldeoes[i].caminho.size() < 2)                 /// ARRUMAR CAÇA
            {
                switch (aldeoes[i].oQueFazendo)
                {
                case nArvore:
                {
                    int arvoreMaisPerto = procuraArvoreMaisPerto(aldeoes[i].x, aldeoes [i].y, arvores);
                    aldeoes[i].caminho = pathfind(aldeoes[i].x , aldeoes[i].y, arvores[arvoreMaisPerto].x, arvores[arvoreMaisPerto].y, vacas, arvores, aldeoes, townCenter, barracas, guerreiro);
                    /*LimparTela();
                    cout << aldeoes[i].caminho.back().x << " <> "<<aldeoes[i].caminho.back().y ;*//*/**/

                    int a = verificaQueArvore(aldeoes[i].caminho[0].x, aldeoes[i].caminho[0].y, arvores);
                    if (a != -1)
                    {
                        arvores[a].qtdDeMadeiraRestante--;
                        madeira++;
                        cout <<'\a';
                        if (arvores[a].qtdDeMadeiraRestante == 0)
                        {
                            arvores.erase(arvores.begin()+a);
                            //procuraArvoreMaisPerto();
                            //aldeoes[i].caminho.clear();
                        }
                        andaNessa=false;
                    }
                    break;
                }
                case nVaca:
                {
                    int vacaMaisPerto = procuraVacaMaisPerto(aldeoes[i].x, aldeoes [i].y, vacas);
                    aldeoes[i].caminho = pathfind(aldeoes[i].x , aldeoes[i].y, vacas[vacaMaisPerto].x, vacas[vacaMaisPerto].y, vacas, arvores, aldeoes, townCenter, barracas, guerreiro);
                    int a = verificaQueVaca(aldeoes[i].caminho[0].x, aldeoes[i].caminho[0].y, vacas);
                    if (a != -1)
                    {
                        vacas[a].estaViva = false;
                        vacas[a].qtdDeComidaRestante--;
                        comida++;
                        if (vacas[a].qtdDeComidaRestante == 0)
                        {
                            vacas.erase(vacas.begin()+a);
                            //aldeoes[i].caminho.clear();
                        }
                        andaNessa=false;
                    }
                    break;
                }

                }

            }
            if (andaNessa && (aldeoes[i].xDest != aldeoes[i].x || aldeoes[i].yDest != aldeoes[i].y))
            {
                if (aldeoes[i].oQueFazendo == 0 && (aldeoes[i].caminho.size()==0  || aldeoes[i].caminho.back().x != aldeoes[i].xDest || aldeoes[i].caminho.back().y != aldeoes[i].yDest))
                {
                    aldeoes[i].caminho = pathfind(aldeoes[i].x , aldeoes[i].y, aldeoes[i].xDest, aldeoes[i].yDest, vacas, arvores, aldeoes, townCenter, barracas, guerreiro);
                }
                if (andaNessa && !verificaSeHaAlgumaCoisa(aldeoes[i].caminho[0].x,aldeoes[i].caminho[0].y, vacas, arvores, aldeoes, townCenter,barracas, guerreiro))
                {
                    aldeoes[i].x= aldeoes[i].caminho[0].x;
                    aldeoes[i].y= aldeoes[i].caminho[0].y;
                    aldeoes[i].caminho.erase(aldeoes[i].caminho.begin());
                }
            }
            andaNessa = true;
        }
    }
        for(int i = 0; i < guerreiro.size(); i++)
        {
            bool andaNessa = true;
            andaNessa = true;
            if (guerreiro[i].tempoMovimento < clock())
            {
                guerreiro[i].tempoMovimento = clock() + float(CLOCKS_PER_SEC) * 0.5 * VELOCIDADEDOJOGO;
                if (guerreiro[i].recemEscolhido == true)
                {
                    guerreiro[i].recemEscolhido = false;
                    /*cout <<guerreiro[i].x <<"  "<< guerreiro[i].y<<"<>"<< guerreiro[i].xDest<<"  "<< guerreiro[i].yDest<<flush;
                    sleep(2);*/
                    guerreiro[i].caminho = pathfind(guerreiro[i].x , guerreiro[i].y, guerreiro[i].xDest, guerreiro[i].yDest, vacas, arvores, aldeoes, townCenter, barracas, guerreiro);
                }

                if (guerreiro[i].caminho.size() >0)
                {

                    /*LimparTela();
                    for (int am = 0; am < guerreiro[i].caminho.size(); am++)
                    {
                        cout <<guerreiro[i].caminho[am].x<<" , "<<guerreiro[i].caminho[am].y<<" <-- "<<" <> "<<flush;
                    }
                    sleep(5);
*/
                    guerreiro[i].x = guerreiro[i].caminho[0].x;
                    guerreiro[i].y = guerreiro[i].caminho[0].y;
                    guerreiro[i].caminho.erase(guerreiro[i].caminho.begin());
                }
        }
  }  ///outros objetos

}
void desenho(int &TAMX, int &TAMY, int xDoJogador, int yDoJogador,int comida,int madeira,vector <ARVORE> arvores, vector<VACA> vacas, vector <CIDADAO> aldeoes, vector <LIMITE> limites, ONIBUS townCenter, MODOCONSTRUCAO modoConstrucao, vector <BARRACK> barracas, vector<GUERREIRO> guerreiro)
{
    LimparTela();
    gotoXY(1,1);
    cout <<LIMPA<<flush;
    cout << AZULFUNDOVERDE <<"COMIDA : " <<AMARELOFUNDOVERDE<< comida<<     //xDoJogador<<
         AZULFUNDOVERDE<<"   MADEIRA : "<<AMARELOFUNDOVERDE <<madeira<<"                                                "<<xDoJogador + TAMX/2<<", "<<yDoJogador+TAMY/2-1;

    if (modoConstrucao.ligado == true)
    {
        modoConstrucao.mostar(TAMX/2 -3, TAMY/2 -1);
    }
    if (townCenter.x > xDoJogador && townCenter.x < xDoJogador+TAMX - 5 &&
            townCenter.y > yDoJogador && townCenter.y < yDoJogador + TAMY-2)
        townCenter.mostrar(xDoJogador, yDoJogador);

    for (unsigned int i =0; i < arvores.size(); i++)
    {
        if (arvores[i].x > xDoJogador && arvores[i].x < xDoJogador + TAMX + 1&&
                arvores[i].y > yDoJogador && arvores[i].y < yDoJogador + TAMY)
        {
            gotoXY(arvores[i].x - xDoJogador , arvores[i].y - yDoJogador+1);
            cout << arvores[i].imagem;
        }
    }

    for (unsigned int i =0; i < limites.size(); i++)
    {
        if (limites[i].x > xDoJogador && limites[i].x < xDoJogador + TAMX + 1&&
                limites[i].y > yDoJogador && limites[i].y < yDoJogador + TAMY)
        {
            gotoXY(limites[i].x - xDoJogador , limites[i].y - yDoJogador+1);
            cout << limites[i].imagem;
        }
    }

    for (unsigned int i =0; i < vacas.size(); i++)
    {
        if (vacas[i].x > xDoJogador && vacas[i].x < xDoJogador + TAMX + 1&&
                vacas[i].y > yDoJogador && vacas[i].y < yDoJogador + TAMY)
        {
            gotoXY(vacas[i].x - xDoJogador , vacas[i].y - yDoJogador+1);
            cout << ((vacas[i].estaViva) ? vacas[i].imagem : vacas[i].imagemMorta);
        }
    }

    for (unsigned int i =0; i < aldeoes.size(); i++)
    {
        if (aldeoes[i].x > xDoJogador && aldeoes[i].x < xDoJogador + TAMX + 1&&
                aldeoes[i].y > yDoJogador && aldeoes[i].y < yDoJogador + TAMY)
        {
            aldeoes[i].mostrar(xDoJogador, yDoJogador);
        }
    }
    for (unsigned int i =0; i < guerreiro.size(); i++)
    {
        if (guerreiro[i].x > xDoJogador && guerreiro[i].x < xDoJogador + TAMX + 1&&
                guerreiro[i].y > yDoJogador && guerreiro[i].y < yDoJogador + TAMY)
        {
            guerreiro[i].mostrar(xDoJogador, yDoJogador);
        }
    }
    for (unsigned int i = 0; i < barracas.size(); i++)
    {
        if (barracas[i].x > xDoJogador && barracas[i].x < xDoJogador+TAMX - 5 &&
                barracas[i].y > yDoJogador && barracas[i].y < yDoJogador + TAMY-2)
            barracas[i].mostrar(xDoJogador, yDoJogador);
    }
    gotoXY(TAMX/2,TAMY/2);//final
}


vector <XY> pathfind(int xComeco,int yComeco ,int &xDest, int &yDest, vector <VACA> vacas, vector <ARVORE> arvores, vector<CIDADAO> aldeoes, ONIBUS townCenter, vector <BARRACK> barracas, vector<GUERREIRO> guerreiro)
{
    /*
        1
       4 2
        3
    */
    vector <XY> listaAberta;

    vector <XY> listaFinal;

    //bool possivel = !verificaSeHaAlgumaCoisa(xComeco, yComeco, vacas, arvores, aldeoes);

    {
        XY a(xComeco, yComeco, 0, (abs(xComeco - xDest) + abs(yComeco - yDest)));
        a.anterior=-1;
        listaAberta.push_back(a);
    }

    int numeroASerVerificado;
    vector <XY> listaFechada;

    while (true)
    {
        if (listaAberta.size()==0 || listaFechada.size()>100)             ///ou acabou = esta preso <> ou esta muito dificil, retorna o caminho + perto
        {
            listaFinal.push_back(listaFechada[menorH(listaFechada)]);
            xDest = listaFinal[0].x;
            yDest = listaFinal[0].y;
            break;
        }
        numeroASerVerificado = menorF(listaAberta);
        {
            listaFechada.push_back (listaAberta[numeroASerVerificado]);

            /*if (listaFechada.back().x == xDest&&listaFechada.back().y == yDest)
            {
                listaFinal.push_back(listaFechada.back());
                break;
            }*/



            if (listaAberta[numeroASerVerificado].x == xDest && listaAberta[numeroASerVerificado].y - 1 == yDest)
            {
                XY a(listaAberta[numeroASerVerificado].x, listaAberta[numeroASerVerificado].y - 1, listaAberta[numeroASerVerificado].g+1 ,
                     (abs(listaAberta[numeroASerVerificado].x - xDest) + abs(listaAberta[numeroASerVerificado].y -1 - yDest)));
                a.anterior = listaFechada.size()-1;
                listaFinal.push_back (a);//ver se precisa por na lista fechada
                break;
            }
            if (!verificaSeHaAlgumaCoisaPath(listaAberta[numeroASerVerificado].x, listaAberta[numeroASerVerificado].y - 1 , vacas, arvores, aldeoes, listaAberta, listaFechada, townCenter, barracas, guerreiro))
            {
                XY a(listaAberta[numeroASerVerificado].x, listaAberta[numeroASerVerificado].y - 1, listaAberta[numeroASerVerificado].g+1 ,
                     (abs(listaAberta[numeroASerVerificado].x - xDest) + abs(listaAberta[numeroASerVerificado].y -1 - yDest)));
                a.anterior = listaFechada.size()-1;
                listaAberta.push_back(a);
            }

            if (listaAberta[numeroASerVerificado].x +1 == xDest && listaAberta[numeroASerVerificado].y == yDest)
            {
                XY a(listaAberta[numeroASerVerificado].x+1, listaAberta[numeroASerVerificado].y, listaAberta[numeroASerVerificado].g+1 ,
                     (abs(listaAberta[numeroASerVerificado].x+1 - xDest) + abs(listaAberta[numeroASerVerificado].y - yDest)));
                a.anterior = listaFechada.size()-1;
                listaFinal.push_back (a);//ver se precisa por na lista fechada
                break;
            }
            if (!verificaSeHaAlgumaCoisaPath(listaAberta[numeroASerVerificado].x+1, listaAberta[numeroASerVerificado].y, vacas, arvores, aldeoes, listaAberta, listaFechada, townCenter, barracas, guerreiro))
            {
                XY a(listaAberta[numeroASerVerificado].x+1, listaAberta[numeroASerVerificado].y, listaAberta[numeroASerVerificado].g+1 ,
                     (abs(listaAberta[numeroASerVerificado].x+1 - xDest) + abs(listaAberta[numeroASerVerificado].y - yDest)));
                a.anterior = listaFechada.size()-1;
                listaAberta.push_back(a);
            }

            if (listaAberta[numeroASerVerificado].x  == xDest && listaAberta[numeroASerVerificado].y+1 == yDest)
            {
                XY a(listaAberta[numeroASerVerificado].x, listaAberta[numeroASerVerificado].y+1, listaAberta[numeroASerVerificado].g+1 ,
                     (abs(listaAberta[numeroASerVerificado].x - xDest) + abs(listaAberta[numeroASerVerificado].y+1 - yDest)));
                a.anterior = listaFechada.size()-1;
                listaFinal.push_back (a);//ver se precisa por na lista fechada
                break;
            }
            if (!verificaSeHaAlgumaCoisaPath(listaAberta[numeroASerVerificado].x, listaAberta[numeroASerVerificado].y + 1 , vacas, arvores, aldeoes, listaAberta, listaFechada, townCenter, barracas, guerreiro))
            {
                XY a(listaAberta[numeroASerVerificado].x, listaAberta[numeroASerVerificado].y + 1, listaAberta[numeroASerVerificado].g+1 ,
                     (abs(listaAberta[numeroASerVerificado].x - xDest) + abs(listaAberta[numeroASerVerificado].y +1 - yDest)));
                a.anterior = listaFechada.size()-1;
                listaAberta.push_back(a);
            }

            if (listaAberta[numeroASerVerificado].x -1 == xDest && listaAberta[numeroASerVerificado].y == yDest)
            {
                XY a(listaAberta[numeroASerVerificado].x-1, listaAberta[numeroASerVerificado].y, listaAberta[numeroASerVerificado].g+1 ,
                     (abs(listaAberta[numeroASerVerificado].x-1 - xDest) + abs(listaAberta[numeroASerVerificado].y - yDest)));
                a.anterior = listaFechada.size()-1;
                listaFinal.push_back (a);//ver se precisa por na lista fechada
                break;
            }
            if (!verificaSeHaAlgumaCoisaPath(listaAberta[numeroASerVerificado].x-1, listaAberta[numeroASerVerificado].y  , vacas, arvores, aldeoes, listaAberta, listaFechada, townCenter, barracas, guerreiro))
            {
                XY a(listaAberta[numeroASerVerificado].x-1, listaAberta[numeroASerVerificado].y , listaAberta[numeroASerVerificado].g+1 ,
                     (abs(listaAberta[numeroASerVerificado].x-1 - xDest) + abs(listaAberta[numeroASerVerificado].y  - yDest)));
                a.anterior = listaFechada.size()-1;
                listaAberta.push_back(a);
            }
            listaAberta.erase(listaAberta.begin() + numeroASerVerificado);

            /*LimparTela();
            for (int i = 0; i < listaFechada.size(); i++)
            {
                cout <<listaFechada[i].x<<" , "<<listaFechada[i].y<<" <-- "<<listaFechada[i].anterior <<" <> "<<flush;
            }
            sleep(2);*/

        }

    }
    /*LimparTela();
            for (int i = 0; i < listaFechada.size(); i++)
            {
                cout <<listaFechada[i].x<<" , "<<listaFechada[i].y<<" <-- "<<listaFechada[i].anterior <<" <> "<<flush;
            }
            sleep(5);*/
    int numeroASerAdicionado = listaFinal[0].anterior;
    while (numeroASerAdicionado!= 0 && numeroASerAdicionado!= -1)
    {
        listaFinal.push_back(listaFechada[numeroASerAdicionado]);
        numeroASerAdicionado = listaFechada[numeroASerAdicionado].anterior;
    }
    /*LimparTela();
            for (int i = 0; i < listaFinal.size(); i++)
            {
                cout <<listaFinal[i].x<<" , "<<listaFinal[i].y<<" <-- "<<" <> "<<flush;
            }
            sleep(5);*/
    vector <XY> listaFinalMesmo;
    for (int i = listaFinal.size() -1; i !=-1; i-- )
    {
        listaFinalMesmo.push_back(listaFinal[i]);
    }
    /*LimparTela();
    for (int i = 0; i < listaFinalMesmo.size(); i++)
    {
        cout <<listaFinalMesmo[i].x<<" , "<<listaFinalMesmo[i].y<<" <-- "<<" <> "<<flush;
    }
    sleep(5);*/
    if (numeroASerAdicionado!=-1)
    {
        xDest = listaFinalMesmo[listaFinalMesmo.size()-1].x;
        yDest = listaFinalMesmo[listaFinalMesmo.size()-1].y;
    }
    return listaFinalMesmo;
}

int menorF(vector <XY> listaAberta)
{
    int numeroASerRetornado = 0;
    for (unsigned int i = 0; i < listaAberta.size(); i++)
        if (listaAberta[i].f < listaAberta[numeroASerRetornado].f)
            numeroASerRetornado = i;

    return numeroASerRetornado;
}
int menorH(vector <XY> listaFechada)
{
    int teste  =listaFechada.size();
    int numeroASerRetornado = 0;
    for (unsigned int i = listaFechada.size()-1 ; i != -1; i--)
        if (listaFechada[i].h <= listaFechada[numeroASerRetornado].h)
            numeroASerRetornado = i;

    return numeroASerRetornado;
}


